<template>
  <page-list
    show-tag-columns
    show-tag-filter
    show-tag-config
    :list="list"
    :columns="columns"
    :single-actions="singleActions"
    :group-actions="groupActions"
    :showSearchbox="showSearchbox"
    :showSingleActions="showActions"
    :showGroupActions="showActions && showGroupActions"
    :export-data-options="exportDataOptions"
    :tag-config-params="tagConfigParams" />
</template>

<script>
import * as R from 'ramda'
import { mapGetters } from 'vuex'
import { surpportLb } from '@Network/views/lb/constants'
import ListMixin from '@/mixins/list'
import WindowsMixin from '@/mixins/windows'
import { getNameFilter, getBrandFilter, getTenantFilter, getDomainFilter, getAccountFilter, getStatusFilter, getCloudProviderFilter, getDescriptionFilter, getCreatedAtFilter } from '@/utils/common/tableFilter'
import { getEnabledSwitchActions, disableDeleteAction } from '@/utils/common/tableActions'
import expectStatus from '@/constants/expectStatus'
import { PROVIDER_MAP } from '@/constants'
import { changeToArr } from '@/utils/utils'
import GlobalSearchMixin from '@/mixins/globalSearch'
import { validateEnabled, validateDisable } from '../utils'
import SingleActionsMixin from '../mixins/singleActions'
import ColumnsMixin from '../mixins/columns'

export default {
  name: 'LbList',
  mixins: [WindowsMixin, ListMixin, GlobalSearchMixin, ColumnsMixin, SingleActionsMixin],
  props: {
    id: String,
    getParams: {
      type: [Function, Object],
    },
    cloudEnv: {
      type: String,
    },
    cloudEnvOptions: {
      type: Array,
    },
  },
  data () {
    const allBrandsFilter = getBrandFilter()
    const filterOptions = {
      external_id: {
        label: this.$t('table.title.external_id'),
      },
      id: {
        label: this.$t('table.title.id'),
      },
      name: getNameFilter(),
      description: getDescriptionFilter(),
      status: getStatusFilter('lb'),
      address: {
        label: this.$t('network.text_248'),
      },
      brand: {
        ...allBrandsFilter,
        items: allBrandsFilter.items.filter(val => surpportLb.includes(val.key.toLowerCase())),
      },
      projects: getTenantFilter(),
      project_domains: getDomainFilter(),
      cloudaccount: getAccountFilter(),
      manager: getCloudProviderFilter(),
      region: {
        label: this.$t('dashboard.text_101'),
      },
      zone: {
        label: this.$t('compute.text_270'),
        hiddenField: 'region',
      },
      created_at: getCreatedAtFilter(),
    }
    const { path } = this.$route
    if (path.includes('/cluster')) {
      delete filterOptions.brand
      delete filterOptions.cloudaccount
    }
    return {
      list: this.$list.createList(this, {
        ctx: this,
        id: this.id,
        resource: 'loadbalancers',
        getParams: this.getParam,
        filterOptions,
        steadyStatus: {
          status: Object.values(expectStatus.lb).flat(),
        },
        responseData: this.responseData,
        hiddenColumns: ['metadata', 'account', 'cluster', 'created_at'],
        autoHiddenFilterKey: 'slb_hidden_columns',
      }),
      exportDataOptions: {
        items: [
          { label: 'ID', key: 'id' },
          { label: this.$t('table.title.external_id'), key: 'external_id' },
          { label: this.$t('network.text_21'), key: 'name' },
          { label: this.$t('network.text_248'), key: 'address' },
          { label: 'VPC', key: 'vpc', hidden: this.$store.getters.isProjectMode },
          { label: this.$t('network.text_27'), key: 'status' },
          { label: this.$t('network.text_192'), key: 'charge_type' },
          { label: this.$t('network.text_249'), key: 'loadbalancer_spec' },
          { label: this.$t('dictionary.domain'), key: 'project_domain', hidden: this.$store.getters.isProjectMode },
          { label: this.$t('network.text_43'), key: 'tenant' },
          { label: this.$t('network.text_199'), key: 'region' },
          { label: this.$t('network.text_196'), key: 'account', hidden: this.$store.getters.isProjectMode },
          { label: this.$t('common_715'), key: 'user_tags' },
          { label: this.$t('common.createdAt'), key: 'created_at' },
        ],
      },
      tagConfigParams: {
        resource: 'loadbalancers',
        queryTreeId: 'project-tag-value-tree',
      },
    }
  },
  computed: {
    ...mapGetters(['userInfo', 'capability']),
    showActions () {
      return !this.$isScopedPolicyMenuHidden('slb_hidden_columns.perform_action')
    },
    groupActions () {
      let createBtn = {
        label: this.$t('network.text_26'),
        permission: 'lb_loadbalancers_create',
        action: () => {
          this.$router.push({
            path: '/lb/create',
            query: {
              type: this.cloudEnv,
            },
          })
        },
        meta: () => {
          return {
            buttonType: 'primary',
            validate: !this.cloudEnvEmpty,
            tooltip: this.cloudEnvEmpty ? this.$t('common.no_platform_available') : '',
          }
        },
      }
      if (this.getParam() && this.getParam().cluster) {
        createBtn = {
          label: this.$t('network.text_26'),
          permission: 'lb_loadbalancers_create',
          action: () => {
            this.$router.push({
              path: '/lb/create',
              query: {
                type: 'Onecloud',
              },
            })
          },
          meta: () => {
            return {
              buttonType: 'primary',
              validate: this.hasService(this.userInfo, 'lbagent'),
            }
          },
        }
      }
      const actions = [
        createBtn,
        {
          label: this.$t('network.text_201'),
          permission: 'lb_loadbalancers_perform_syncstatus',
          action: () => {
            this.onManager('batchPerformAction', {
              steadyStatus: ['running', 'ready'],
              managerArgs: {
                action: 'syncstatus',
              },
            })
          },
          meta: () => {
            const ret = {
              validate: this.list.selectedItems.length > 0,
            }
            const isExist = this.list.selectedItems.some(item => item.brand.toLowerCase() === 'onecloud')
            if (isExist) {
              ret.validate = false
              ret.tooltip = this.$t('network.text_652')
              return ret
            }
            return ret
          },
        },
        {
          label: this.$t('network.text_200'),
          actions: () => {
            return [
              {
                label: this.$t('compute.perform_change_owner', [this.$t('dictionary.project')]),
                permission: 'lb_loadbalancers_perform_change_owner',
                action: () => {
                  this.createDialog('ChangeOwenrDialog', {
                    data: this.list.selectedItems,
                    custom_columns: this.columns.filter(o => ['name', 'address', 'tenant'].includes(o.field)),
                    onManager: this.onManager,
                    name: this.$t('network.text_714'),
                    resource: 'loadbalancers',
                  })
                },
                meta: () => {
                  const ret = {
                    validate: false,
                    tooltip: null,
                  }
                  ret.validate = true
                  return ret
                },
              },
              ...getEnabledSwitchActions(this, undefined, ['lb_loadbalancers_perform_enable', 'lb_loadbalancers_perform_disable'], {
                actions: [
                  (obj) => {
                    const ids = this.list.selectedItems.map(item => item.id)
                    this.onManager('batchPerformAction', {
                      steadyStatus: Object.values(expectStatus.lb).flat(),
                      id: ids,
                      managerArgs: {
                        action: 'status',
                        data: {
                          status: 'enabled',
                        },
                      },
                    })
                  },
                  (obj) => {
                    const ids = this.list.selectedItems.map(item => item.id)
                    this.onManager('batchPerformAction', {
                      steadyStatus: Object.values(expectStatus.lb).flat(),
                      id: ids,
                      managerArgs: {
                        action: 'status',
                        data: {
                          status: 'disabled',
                        },
                      },
                    })
                  },
                ],
                metas: [
                  () => {
                    return validateEnabled(this.list.selectedItems)
                  },
                  () => {
                    return validateDisable(this.list.selectedItems)
                  },
                ],
              }),
              {
                label: this.$t('network.text_253'),
                permission: 'lb_loadbalancers_update',
                action: () => {
                  this.createDialog('LbUpdateCluster', {
                    title: this.$t('network.text_253'),
                    data: this.list.selectedItems,
                    columns: this.columns,
                    onManager: this.onManager,
                    refresh: this.refresh,
                  })
                },
                meta: () => {
                  const zonsIds = {}
                  const isOneCloud = this.list.selectedItems.every(item => {
                    zonsIds[item.zone_id] = true
                    return item.brand === 'OneCloud'
                  })
                  if (!isOneCloud) {
                    return {
                      validate: false,
                      tooltip: this.$t('network.text_254'),
                    }
                  }
                  if (Object.keys(zonsIds).length > 1) {
                    return {
                      validate: false,
                      tooltip: this.$t('network.text_255'),
                    }
                  }
                  return {
                    validate: true,
                  }
                },
              },
              {
                label: this.$t('table.action.set_tag'),
                permission: 'lb_loadbalancers_perform_set_user_metadata',
                action: () => {
                  this.createDialog('SetTagDialog', {
                    data: this.list.selectedItems,
                    columns: this.columns,
                    onManager: this.onManager,
                    mode: 'add',
                    params: {
                      resources: 'loadbalancer',
                    },
                  })
                },
              },
              disableDeleteAction(this, {
                name: this.$t('dictionary.loadbalancer'),
                permission: 'lb_loadbalancers_update',
              }),
              {
                label: this.$t('network.text_131'),
                permission: 'lb_loadbalancers_delete',
                action: () => {
                  this.createDialog('DeleteLbDialog', {
                    vm: this,
                    title: this.$t('network.text_131'),
                    data: this.list.selectedItems,
                    columns: this.columns,
                    onManager: this.onManager,
                  })
                },
                meta: () => {
                  return {
                    validate: this.list.allowDelete(),
                  }
                },
              },
            ]
          },
          meta: () => {
            let ret = {
              validate: true,
              tooltip: null,
            }
            ret.validate = this.list.selectedItems.length > 0
            if (!ret.validate) return ret

            const hasAzure = this.list.selectedItems.filter((item) => {
              return item.provider && item.provider.toLowerCase() === 'azure'
            })
            if (hasAzure.length > 0) return { validate: false, tooltip: this.$t('network.text_309', [PROVIDER_MAP[hasAzure[0].provider].label]) }

            const hasGoogle = this.list.selectedItems.filter((item) => {
              return item.provider && item.provider.toLowerCase() === 'google'
            })
            if (hasGoogle.length > 0) return { validate: false, tooltip: this.$t('network.text_309', [PROVIDER_MAP[hasGoogle[0].provider].label]) }
            ret = this.$isValidateResourceLock(this.list.selectedItems)
            return ret
          },
        },
      ]
      return actions
    },
  },
  watch: {
    cloudEnv (val) {
      switch (val) {
        case 'onpremise':
          this.envParams = { is_on_premise: true }
          break
        case 'private':
          this.envParams = { private_cloud: true }
          break
        case 'public':
          this.envParams = { public_cloud: true }
          break
        default:
          this.envParams = {}
      }
      const params = this.list.getParams
      delete params.is_on_premise
      delete params.private_cloud
      delete params.public_cloud
      this.list.getParams = { ...params, ...this.envParams }
      this.list.fetchData()
    },
  },
  created () {
    this.list.fetchData()
  },
  methods: {
    getParam () {
      const ret = {
        ...(R.is(Function, this.getParams) ? this.getParams() : this.getParams),
      }
      return ret
    },
    hasService ($userInfo, service) {
      if ($userInfo && $userInfo.services && $userInfo.services.length) {
        const results = $userInfo.services.filter(item => {
          return item.type === service && item.status === true
        })
        return results && results.length > 0
      }
      return false
    },
    hasHypervisors (hypervisor) {
      const hypervisors = changeToArr(hypervisor)
      for (let i = 0, len = hypervisors.length; i < len; i++) {
        if ((this.capability.hypervisors || []).indexOf(hypervisors[i]) !== -1) {
          return true
        }
      }
      return false
    },
    handleOpenSidepage (row, tab) {
      this.sidePageTriggerHandle(this, 'LbSidePage', {
        id: row.id,
        resource: 'loadbalancers',
        getParams: this.getParam,
        steadyStatus: {
          status: Object.values(expectStatus.lb).flat(),
        },
      }, {
        row: row,
        list: this.list,
        tab,
      })
    },
  },
}
</script>
